package com.mali.user.util;

import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.mali.common.exception.UnAuthException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.security.KeyPair;
import java.time.Duration;
import java.util.Date;

@Slf4j
@Component
public class JwtUtil {

    private final JWTSigner jwtSigner;

    // 构造函数注入密钥对
    public JwtUtil(KeyPair keyPair) {
        this.jwtSigner = JWTSignerUtil.createSigner("rs256", keyPair);
    }

    /**
     * 创建 Token
     *
     * @param userId 用户ID
     * @param ttl 有效期
     * @return 签名后的token
     */
    public String createToken(Long userId, Duration ttl) {
        return JWT.create()
                .setPayload("user", userId)
                .setExpiresAt(new Date(System.currentTimeMillis() + ttl.toMillis()))
                .setSigner(jwtSigner)
                .sign();
    }

    /**
     * 解析 Token 并提取 userId
     */
    public Long parseToken(String token) {
        if (token == null || token.isBlank()) {
            throw new UnAuthException("Token 不能为空");
        }

        JWT jwt;
        try {
            jwt = JWT.of(token).setSigner(jwtSigner);
        } catch (Exception e) {
            log.warn("Token 格式错误: {}", e.getMessage());
            throw new UnAuthException("无效的 Token");
        }

        if (!jwt.verify()) {
            throw new UnAuthException("Token 验证失败");
        }

        try {
            JWTValidator.of(jwt).validateDate();
        } catch (ValidateException e) {
            throw new UnAuthException("Token 已过期");
        }

        Object userPayload = jwt.getPayload("user");
        if (userPayload == null) {
            throw new UnAuthException("Token 缺少用户信息");
        }

        try {
            return Long.valueOf(userPayload.toString());
        } catch (NumberFormatException e) {
            throw new UnAuthException("Token 中用户信息格式错误");
        }
    }
}
